Loading...
 

Unloading and loading a ClassiX® database

Unloading and loading a ClassiX® database

1. objectives and procedure

2. calling up the programmes

2.1 Call parameters of the programme CXUOSR.EXE (Unloading)

2.2 Call parameters for CXCOSR.EXE (checksum calculation)

2.3 Call parameters of the programme CXLOSR.EXE (load)

2.4 Example - a batch file

3. clustering

4. database analysis

5. cross-reference of the objects

1. objectives and procedure

The database is written to sequential files in ASCII format (DATABASE.DMP, FREEOBJ1.DMP, ...), which are in principle also readable for humans. They contain all information about the objects in the database, which is necessary to reconstruct these objects in a new database with the same data and to reconstruct all relations between the objects. Thereby the distribution of the objects to sub-databases, segments and clusters can be changed - this is usually the aim of such an operation.
Unload - Load is also an alternative to the schema evolution provided by ObjectStore (conversion of the database to a new schema, i.e. modified class definitions). During unloading the following information is lost:

  • Objects that can no longer be reached (neither via a root entry point collection nor via a relation that starts from at least one other reachable object
  • Indices via collections (including the index manager)

Logically deleted objects, however, remain as long as they are still referenced directly or indirectly by an active object.

The overall procedure - including checksum generation to ensure logical integrity - comprises four sub-steps:

  • Unloading with programme CXUOSR.EXE
    In phase 1 all objects in the root entry point collections are unloaded. In phase 2 it is determined for each previously unloaded object whether relations originating from this object refer to an unloaded object, which is then unloaded. Since such objects also undergo the test just mentioned, the procedure is transitive and at the end of phase 2 all objects accessible via any access path are unloaded. For this purpose a hash table of the (database) addresses of all objects already unloaded is required (TMPFILE.DMP). The objects unloaded in phase 1 can be found in file DATABASE.dmp, the objects from phase 2 in files FREEOBJ1.dmp, FREEOBJ2.dmp, ... For the classes CX_BITMAP, CX_COM_OBJECT and CX_MULTIPLE_COM_OBJECT there is another file per object, which contains the data stream of the object.
    Phase 3 is optional: here the assignment of the objects in the root entry point collections is saved in the file REP_COLLS.dmp.
  • Checksum the "old database" with CXCOSR.EXE (parameter -1)
    All objects in the database are read segment by segment and evaluated with a checksum. When reading the segments, even inaccessible objects are "seen". With the hashtable, which was built up during unloading, they can be distinguished from accessible objects.
  • Loading the new database with CXLOSR.EXE
    Restoring the database also takes place in two phases. In phase 1 all objects are created and the data fields are assigned the corresponding values. Phase 2 is responsible for the reconstruction of the relationships between the objects. In order to make this possible, a hash table with the database addresses of all objects is created in phase 1 - similar to unloading - but here each entry also contains the database address of the new database: references in the "old database" can thus be translated very quickly into references in the "new database".
    The classification of the new objects in the Root-Entrypoint-Colelctions can be controlled by the description in the CLASSIX.INI-File - and thus can be changed compared to the unloaded original database - or can be restored identically by means of the information saved during the unloading in phase 3.
  • Checksum of the "new database" with CXCOSR.EXE (parameter -2)
    A checksum is calculated for each object in the newly loaded database. Matching the checksum of the "old database" guarantees that the data fields of all objects have been restored correctly. In addition, the number of relations emanating from each object is evaluated, which also controls the recovery of the object relationship.
    In case of discrepancies, it is possible to view the objects concerned in both databases.

 load9.GIF (14767 bytes)
This is the procedure if phase 3 of the unload and load program is not used, i.e. the arrangement of the objects in the root entry point collections is determined by the specifications in CLASSIX.INI. The explicit insertion of the objects in phase 3 guarantees an absolutely identical assignment of the objects to the Root-Entrypoint-Collections (see procedure).

Note: Only if the total checksum in CHECKSUM.OLD and CHECKSUM.NEW are identical, the newly created database can be used instead of the unloaded "old" database.

2. calling up the programmes

All flags can start with / or -. Lower and upper case letters are equivalent. A parameter following a flag can be directly following or separated by blanks; for example:

cxuosr /iTS.INI /h5000000

or

cxuosr -I ts.ini /H 5000000

If successful, the programmes will provide the return code 0.

2.1 Call parameters of the programme CXUOSR.EXE (Unloading)

Parameters Meaning Standard assumption
/I fileName Initialisation file CLASSIX.INI
/W fileName Hash Table TMPFILE.DMP
/D workDir Working directory in which all other files are written or read from current directory
/Hn Estimated number n of objects in the database 47977
/F Keep Hash-Table in memory (Fast mode) Hash-Table as file
/EparamFile Hash table on external DCOM servers Hash-Table as file
/1 only phase 1 Phase 1 and 2
/2 only phase 2 Phase 1 and 2
/3 Phase 3
/Cn Pattern for Clustering 0xff or value of the environment variables CX_CLUSTERING
/Mn Calculates the memory size of the hash table for n objects. With this you can estimate if a large database can be unloaded with -F or -E.

The two phases

  • Unloading objects from the root entry point collections
  • Unloading of all those objects that can only be reached via previously unloaded objects

run automatically one after the other if neither /1 nor /2 is specified.
When unloading, it is determined how the objects are grouped in clusters in the new database to be set up.
Phase 3 collects the information about the arrangement of the objects in the root entry point collections.

Phase 1 is restartable. Prerequisite: Hash table is stored in the memory (parameter /E or /F).
If a class has been completely unloaded after a specified time interval, the hash table is saved as file 'filename.nnn', with nnn = { 001, 002, ... }and a flag is written into the unload file (checkpoint).
At such a point you can put on again: Parameter /R. The resulting parts of the discharge data must be joined together at the end, eliminating superfluous information (data discharged between the last checkpoint and abort) - call with parameter /P.
The following overview shows all other flags relevant for restartability:

Parameters Meaning Standard assumption
-Vn Time interval (n in seconds) for restart -V7200 (i.e. 2 hours)
-RclassName,k Restart after class 'className', k = { 1, 2, ... } is the consecutive number of the restart attempt
-Pfile1{restartInfo1},file2{restartInfo2},...,files,outFile Copy files together after n-1 restart, eliminate redundant data

As 'restartInfo' the filename of the rescued hashfile (complete path) has to be entered (see example).

2.2 Call parameters for CXCOSR.EXE (checksum calculation)

Parameters Meaning Standard assumption
/I fileName Initialisation file CLASSIX.INI
/W fileName Hash table (from CXUOSR.exe) TMPFILE.dmp
/G fileName Hash table (from CXLOSR.exe) GATEWAY.dmp
/D workDir Working directory in which all other files are written or read from current directory
/1 Create a checksum of the "old" database none
/2 Create a checksum of the "new" database none
/U fileName Hash table from CXUOSR.EXE (only with /1) TMPFILE.DMP
/F Keep Hash-Table in memory (Fast mode) as file
/EparamFile Hash table on external DCOM servers as file

The checksums for each individual object are written to the file OBJECTS.OLD at /1. If CXCOSR.EXE for the new database is run with /2, the file OBJECTS.NEW is still created, which contains all objects with their checksums. Checksum differences are marked in such a way that the objects concerned can be viewed in both the old and the new database with InstantView® - e.g. with the object inspector - InstantView®-Source: CHECKSUM.CXP. Further functions for analysing objects in the old and new database are provided by the CX_DB_UTILITY object.

The program CXCOSR.EXE provides a further function which is not directly related to the unloading of a database: the creation of an object cross-reference - i.e. an auxiliary database which can be used to determine for each object from which other objects it is referenced

2.3 Call parameters of the programme CXLOSR.EXE (load)

Parameters Meaning Standard assumption
/I fileName Initialisation file CLASSIX.INI
/G fileName Hashfile (gateway from old to new database) GATEWAY.dmp
/D workDir Working directory in which all other files are written or read from current directory
/H nObjects Estimated number of objects in the database 47977
/F Keep Hash-Table in memory (Fast mode) as file
/EparamFile Hash table on external DCOM servers as file
/N DO NOT enter objects in Root-Entrypoint-Colelctions when loading (phase 1), phase 3 is necessary Insert objects directly into REP-Colls, DO NOT use phase 3
/1 only phase 1 (loading, creating objects) Phase 1 and 2
/2 only phase 2 (reconstructing relations) Phase 1 and 2
/3 Phase 3 (insert object in REP collections)
/U to "add" to already existing database Database is newly created
/batch in phase 1: create new database(s) (and delete database(s) of the same name) without interactive confirmation interactive query (must be answered with 'YES')
/Mn Calculates the memory size of the hash table for n objects. This can be used to estimate whether a large database can be loaded with -F.

Here, too, both phases normally (neither /1 nor /2 specified) run automatically one after the other. CXLOSR.EXE generates a protocol in the file LOAD.LOG

The hash table (GATEWAY.DMP) forms the bridge between the old and new database, i.e. for each object location in the old database the location of the corresponding object in the newly loaded database is known. The table can be kept resident in memory during loading: locally (flag /F) or distributed to external servers (flag /E). A "distributed gateway file" can be combined to one file.

2.4 Example - a batch file

cxuosr -Its.ini
if ERRORLEVEL 1 goto EVENING
cxuosr -3 -Its.ini
if ERRORLEVEL 1 goto EVENING
cxcosr -1 -its.ini
if ERRORLEVEL 1 goto EVENING
cxlosr -its.ini -batch
if ERRORLEVEL 1 goto EVENING
cxlosr -its.ini -3
if ERRORLEVEL 1 goto EVENING
cxcosr -2 -its.ini
echo "Database sucessfully reloaded
break
exit
:EVENING
echo "Reload failed

3. clustering

With ObjectStore the data transfer between the database server and the clients is page-oriented. Therefore the arrangement of the objects in the database determines the performance of the applications to a high degree.

The clustering of the objects can be controlled for

In both cases, clustering can be activated or deactivated in stages.

Under the aspect of clustering, an object is either a master or slave object:

A master object is stored in a segment of the database defined for its class; a cluster may be created for the master object. The information about the segment and any cluster to be created is described in the database layout (file CLASSIX.ODB).

If clustering is completely deactivated, there are only master objects - this is the standard assumption in the ClassiX® system.

The position of a slave object in the database determines another object already stored in the database to which it is connected. The creation of such an object with CreatePersObject, CopyPersObject must be delayed until a relation to an object already existing in the database is established. Therefore the mentioned InstantView® commands first create a (transient) object of the class CX_LAZY_CREATOR.
The procedure for unloading/loading a database is different and is described below.

Before doing so, however, the rules that determine when an object is master and when it is not will be discussed.

The clustering rules have been grouped into categories - according to pragmatic considerations - and, by assigning a bit to each category, a pattern is obtained with which the categories can be switched on and off independently of each other.

This pattern is set with the environment variable CX_CLUSTERING; the default setting is CX_CLUSTERING=0.

The following table shows the categories and the associated rules; in addition to the bit in column 1, a name was assigned in the second column.

Column 3 specifies which classes can appear as slave objects. While for elementary objects (e.g. the base classes CX_DATE, CX_VALUE ...) the class affiliation is sufficient as sole criterion, additional conditions are specified for more complex objects:

Bit Category Classes Condition
1 BASIC CX_NUMERIC..., CX_VECTOR_AMOUNT..., CX_TERM..., CX_FORMULA, CX_FCONDITION, CX_NAMED_FCONDITION, CX_CONDITIONED_BAG

but not CX_NAMED_FORMULA

-
2 VALIDITY CX_VALIDITY... -
4 WRAPPER CX_DESCRIPTIVE_REF, CX_OVERWRITING_REF -
8 SLAVE_SEG all no own object segment
16 ZEROPATTERN CX_ATTRIBUTE_SET... REP_pattern = 0
32 ZEROPATTERN CX_PASSWORD..., CX_GENERAL_TERMS..., CX_CONDITION..., CX_ACCESS... REP_pattern = 0
64 TXN CX_TRANSACTION... REP_pattern = 0 &

(if ($ transaction ) transaction = master

else master is a CX_TRANSACTION)

CX_ALLOCATION... REP_pattern = 0 &

if (card allocators > 0) master Î allocators

else true

128 MONITOR CX_ACCOUNT... if ($ owner) owner = master else true
CX_DATA_CUBE...
Dimension[0] = master

  • A... means class A and all classes derived from it
  • REP_pattern is the bit pattern that determines the classification of the object in the REP-Collection; either specified by the description of the class in CLASSIX.ODB or by explicit specification in CreatePersObject
  • Conditions that refer to the master object master are only valid during unloading/loading, with CreatePersObject / CopyPersObject a CX_LAZY_CREATOR is always created
  • If an object is created with CreatePersObject, the additional condition REP_pattern = 0 applies to all categories. A transient object CX_LAZY_CREATOR cannot be inserted into a REP collection.


The above rules should not only control the clustering produced by means of delayed object creation (CreateOersObject -> CX_LAZY_CREATOR) but should of course also be effective when unloading/loading a database.

The arrangement of the objects in the new database is already determined when unloading:

If a master object o is unloaded, all objects directly accessible by it via relations (pointers / collections) or are tested according to the above rules, whereby objects o takes on the role of the master. If there are slave objects among the objects, they are unloaded next and marked as belonging to o in the unload file.

When unloading the slave objects the same happens, the or take over the role of the master and all objects accessible by them are tested to see if they can be "clustered" by or. Also these indirectly reached objects get into the cluster belonging to object o. Object o then determines when loading the database how all objects subordinated to it are to be stored.

An object o "asks" all objects referenced by it whether they can be "clustered" by o.

Accordingly, it is important in which order the objects are unloaded.

During unloading, priority numbers (from 0 to 5) are assigned to the classes. In phase 1, all objects are unloaded from the in root entry point collections, with classes with low priority numbers coming first:

Priority number
0 CX_ATOM_TABLE, CX_UNIT_PARAMETER
1 CX_MULTIPLE_COM_OBJECT
2 REP_pattern in CLASSIX.ODB > 0 and 0, 1, 4 or 5 does not apply
3 REP_pattern in CLASSIX.ODB > 0 and 0, 1, 4 or 5 does not apply
4 CX_DESCRIPTIVE_REF, CX_OVERWRITING_REF
5 CreatePersObject would create CX_LAZY_CREATOR

Within the same category the classes are unloaded according to the order of the class descriptions in CLASSIX.ODB, i.e.
also the order of the class statements in CLASSIX.ODB influences the clustering

4. database analysis

If the database contains even a single corrupt object, the unload process will generally terminate with a program error.

Program CXAOSR.EXE can detect such errors in an analysis run and write them to a report file:

Parameters Meaning

Standard assumption

/I fileName Initialisation file CLASSIX.INI
/D workDir Working directory in which all other files are written or read from current directory
/A Analysis of the entire database none
/AsegmentName Analysis only for the specified segment none
/AsegX-segY Analysis from segment segX to segY none
/AsegX- Analysis from segment segX to end none
/A-segY Analysis (from start) to segment segY (inclusive)
/An%-m% bzw. /An%- oder /A-%m
as above, select segments segX, segY with percentage relative to the size of the database
segX corresponds to n % of the database size, segY corresponds to m%; condition n < m
none
/R Analysis of all REP Collections none
/R repName Analysis of the REP collection with the given name
/P iptFile1,iptFile2,...,iptFilen,outFile,xRefFile[,W]
Postprocessing Analyze-Files, only errors referring to corrupt objects are taken over, file for controlling the partial X-reference is generated, 'W' = copied 'WRAPPER' into this file /Panalyze.lst,analyze2.lst,xObjects.lst

Example: Distribute analysis runs for a large database on three PCs: cxaosr /A-33%, cxaosr /A34%-66%, cxaosr /A67%-

Note: In a batch file, remember the syntax of the parameters: double the percentage signs, e.g.: cxaosr /A34%%-66%%!

During the analysis (with flag /A...) the virtual function SanityCheck() is called for each object. A return code > 0 signals an error:

Slots

1 Slot: Pointer to data = NULL (or dynamic_cast fails)
2 Slot: Pointer corrupt (mapping into real memory fails)
3 Slot - unknown data type (not in the dictionary)
4 Error in frame: n < g
5 Error in frame: n < 0 or g < 0
6 Error in frame: g > 0 but no slot vector allocated
7 DeleteSlot has not reset data pointer (to NULL) ... harmless
8 Slot name = 0
9 dynamic slot (see AssignSlot) - slot not in the dictionary
10 dynamic slot (see AssignSlot) - no relation to defined expression
13 anonymous slot (see CX_OVERWRITING_REF) - no reference to overwrite expression


Objects

20 - 22 CXB_MULTIPLE_STRING: Contradiction number - allocated strings
24 CXB_MULTIPLE_STRING: Partial string cannot be dereferenced
30, 31 CX_NUMERIC corrupt
32 Unit corrupt
33 value 94967254 !!!
41 CX_DESCRIPTIVE_REF and derived - Pointer to "Wrapper" corrupt
(dynamic_cast fails)
42 CX_DESCRIPTIVE_REF and derived - Pointer to "Wrapper" corrupt
(mapping into real memory fails)
50 CX_EXPANDABLE and derived - classID incorrect
71-73 CX_SPAN_DATE
80, 81 CX_PERIODIC_DATE
85, 86 CX_DATETIME
87-89 CX_GLOBAL_DATETIME
100-107 CX_LOCALE ...
391 CX_FORMULA - Expression contradicts syntax
400 CX_CONDITIONED_BAG - Chain of CX_FCONDITIONs corrupt
(dynamic_cast fails)
401 CX_CONDITIONED_BAG with "foreign" CX_FCONDITION (fCond->parent != this)
402 CX_CONDITIONED_BAG - Chain of CX_FCONDITIONs corrupt
(mapping into real memory fails)
501 CX_COM_OBJECT without data (persistentDataStream == NULL)
511 CX_MULTIPLE_COM_OBJECT contains at least one CX_COM_OBJECT without data

SanityCheck also calls itself up for members registered in the DDI, provided that the object in question is a property. In case of an error, the original error code + 10000 is returned.

Furthermore, relations to other objects are analysed (function CheckReferences):

Error
285 active object references (logically) deleted object
286 (logical) deleted object references active object
287 Reference corrupt (dynamic_cast fails)
316 Reference corrupt (ObjectStore Exception)
317 Reference corrupt (undefined exception - caught with catch(...))
318 NULL Pointer in Collection
319 Coll. corrupt (undefinable error, caught with catch(...)
376 Coll. with cardinality c < 0 or c > 10 000 000
377 Coll. - infinite iteration
378 Coll. with Cardinality by 1 too large
379 Coll. with too much cardinality
380 Coll. with too small cardinality
207 Type of referenced object contradicts DDI / Slot-Dictionary (Pointer)
211 Type of referenced object contradicts DDI / Slot-Dictionary (Collection)
2001 ObjectStore Exception already when calling the function SanityCheck() or CheckReferences()
2002 undefined exception already when calling the function SanityCheck() or CheckReferences()

Functions of the CX_DB_UTILITY object support an effective analysis of the error log.

5. cross-reference of the objects

Often it would be of interest to know for a certain object o all objects or which reference the object o, i.e. all objects or which have a pointer to o or a collection with o as element.

This information is kept in objects of the class CX_XREF. Building a cross-reference means that for each object exactly one CX_XREF object is created, which refers to all objects that reference the object represented by the CX_XREF object.

It makes sense to keep the CX_XREF objects in a separate physical database - after all, they are only a snapshot that will soon lose its relevance. CX_XREF objects refer to "normal" objects - but not vice versa. The physical sub-database for the cross-reference can therefore be deleted at any time without affecting the "actual" database.

The assignment of an object to "its" CX_XREF object is realised outside the database (in the gateway file).
The function GetObjectsReferringTo() of the object manager returns for an object o passed as parameter a collection of all objects or that reference the object o.

For such an object o, to which no other object or refers, no corresponding object of the class CX_XREF is created, unless you request with flag /O that a CX_XREF object is created for each object in order to find "lonely" objects in the database.

Description of an auxiliary database for the cross reference:

MetaInfo
Database(2, CX_XREFDB)

Segment(xrefS, DB(2))

Class(CX_XREF, 51, xref)

File(xref, xref, xref)

Storage(xref, DB(2), xrefS, EP("xrefL0"(LIST)), CSeg(xrefS), Garbage(xrefG0, xrefS))

This description is added to the initialisation file (e.g. classix.ini) as long as you want to work with the cross-reference.

Note:
For performance reasons, the REP collection should be the CX_XREF object of type LIST.
For each object in the source database that is referenced by other objects (most of them) a corresponding object CX_XREF is created. Inserting them into a SET takes more and more time with a growing number of objects.

For large data volumes, a limit value for segment splitting should be specified for the object segment.

Objects of class CX_SLOT_XREF are created in the auxiliary database for the cross-reference of the dynamic data fields. Metainformation for object and slot cross-reference is shown in the following example.

The object-cross-reference is established by using

...

SET CX_XREFDB=myXReferenceDB.cxd

cxgosr -U -I modifiedIniFile.ini -batch

the partial database for auxiliary objects is created.

Afterwards, the cross-reference is built up with CXXOSR.EXE:

Parameters Meaning Standard assumption
/X n cross-reference, n estimated number of objects n = 47977
/X n,objectFile cross-reference, n estimated number of objects, the object designated in the file is ignored (hide) n = 47977
/X objectFile partial cross-reference, i.e. only for the objects specified in the file
/S form only the cross-reference for dynamic data fields Cross-reference for objects
/B Cross-references for object and for dynamic data fields in one run only cross-reference for objects
/O Auxiliary flag for the collection of orphan objects, now for each object of the database an associated CX_XREF object is created CX_XREF objects are only created for referenced objects
/I fileName (modified) initialisation file CLASSIX.INI
/G fileName Hashfile (gateway from old to new database) objects.xrf
/F Keep Hash-Table in memory (Fast mode) as file
/EparamFile Hash table on external DCOM servers as file
/D workDir Working directory in which all other files are written or read from current directory

The function GetObjectsReferringTo() requires the Gateway file.
Gateway files (parameter /E) distributed to several external DCOM servers can therefore be combined with program CXXOSR.EXE:

Parameters Meaning Standard assumption
/Cntotal,gatewayFile1,n1,gatewayFile2,n2,... copies all partial files to GATEWAY.CON

The correct specification of the partial sizes (n1 + n2 + ... = ntotal) is compared with the specifications in the gatewayFilek files.

Sample batch files for building the complete cross-reference can be found here.


Partial cross-reference:
The construction of the object cross-reference is accelerated if only for a certain set of objects { o1, o2, ... } is determined, which objects or one of the given objects { o1, o2, ... } are referenced. In the parameter /X a file is specified, which

  • in the first line contains the estimated number n of objects and optionally the identifier EXCLUDE
  • in the following lines the objects are specified by their location in the database

The prime number for the hash file is calculated from the number n - a larger n improves the performance.
EXCLUDE requires that the given objects are not tested as potential speakers. This is useful when repairing corrupt objects in the database: You want to know which objects refer to the "corrupt" objects, but exclude them from the test.

Example:

2000, EXCLUDE <0|284|0|80f230|10000>, <0|284|0|80f350|10000>, <0|284|0|80f470|10000>, <0|284|0|80f590|10000>, <0|284|0|80f7e0|10000>, <0|284|0|80fa20|10000>, <0|284|0|80fb40|10000>, <0|284|0|80fc60|10000>, <0|284|0|80fd80|10000>, <0|284|0|810360|10000>, <0|284|0|8105bc|10000>, <0|284|0|8106ec|10000>, <0|284|0|810800|10000>, <0|284|0|810920|10000>, <0|284|0|810a40|10000>, <0|284|0|810b60|10000>, <0|284|0|810c80|10000>, <0|284|0|810da0|10000>, <0|284|0|810ec0|10000>, <0|284|0|81157c|10000>, <0|284|0|811914|10000>, <0|284|0|811a84|10000>, <0|284|0|812040|10000>, <0|284|0|812268|10000>, <0|284|0|812320|10000>, <0|504|0|7d13cc|10000>

Commas as separators between the elements are optional.
The number of objects per line is unlimited as long as a line length of 512 characters is not exceeded.

Hide certain objects:
Individual objects can also be excluded from the complete cross-reference. This variant is mainly intended as a tool in case you have to deal with corrupt objects in the database. Structure of the file as shown above.

Database analysis and partial cross-reference together form a tool with which logically or physically corrupt or inconsistent objects in a database can be "repaired" (example procedure).

Note: By means of the cross-reference an object in the database can be replaced by another object (function Substitute of the DB-Utility object).